#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string>
#include <string.h>
#include <vector>
#include"mutex.hpp"
using namespace std;
/*-----------------------------------用RAII的锁模拟抢票--------------------------------------*/
#define NUM 4
int tickets = 1000;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

class ThreadData
{
public:
    ThreadData(int number)
    {
        _name = "thread-" + to_string(number);
    }
public:
    string _name;
};

void* threadRun(void* arg)
{
    ThreadData* td = static_cast<ThreadData*>(arg);
    while(1)
    {
        {
            MutexGuard mutex(&lock);
            if(tickets > 0)
            {
                usleep(1000);  
                cout << td->_name << " grab <-->" << "remain: "<< tickets << endl;
                tickets--;
            }      
            else
            {
                break;
            }              
        }
        usleep(13);         //usleep是为了增加并发度（即让线程被切换），放在不同位置最终输出结果不同，如：放在此处和放在if里   
    }

    return nullptr;
}   

int main()
{
    vector<pthread_t> tids;
    vector<ThreadData*> tds;

    for(int i = 0; i < NUM; i++)
    {
        pthread_t tid = 0;
        ThreadData* td = new ThreadData(i);
        pthread_create(&tid, nullptr, threadRun, td);
        tids.push_back(tid);
        tds.push_back(td);
    }

    for(int i = 0; i < NUM; i++)
    {
        pthread_join(tids[i],nullptr);
    }
    for(auto& e : tds)
    {
        delete e;
    }

    return 0;
}

/*-----------------------------------用系统的锁模拟抢票--------------------------------------*/

// #define NUM 4
// int tickets = 1000;
// class ThreadData
// {
// public:
//     ThreadData(int number,pthread_mutex_t* lock)
//     :_lock(lock)
//     {
//         _name = "thread-" + to_string(number);
//     }
// public:
//     string _name;
//     pthread_mutex_t* _lock;
// };

// void* threadRun(void* arg)
// {
//     ThreadData* td = static_cast<ThreadData*>(arg);
//     while(1)
//     {
//         pthread_mutex_lock(td->_lock);
//         if(tickets > 0)
//         {
//             usleep(1000);  
//             cout << td->_name << " grab <-->" << "remain: "<< tickets << endl;
//             tickets--;
//             pthread_mutex_unlock(td->_lock);
//         }      
//         else
//         {
//             pthread_mutex_unlock(td->_lock);
//             break;
//         }  
//         usleep(13);         //usleep是为了增加并发度（即让线程被切换），放在不同位置最终输出结果不同，如：放在此处和放在if里   

//     }

//     return nullptr;
// }   

// int main()
// {
//     vector<pthread_t> tids;
//     vector<ThreadData*> tds;

//     pthread_mutex_t mutex;
//     pthread_mutex_init(&mutex,nullptr);

//     for(int i = 0; i < NUM; i++)
//     {
//         pthread_t tid = 0;
//         ThreadData* td = new ThreadData(i, &mutex);
//         pthread_create(&tid, nullptr, threadRun, td);
//         tids.push_back(tid);
//         tds.push_back(td);
//     }

//     for(int i = 0; i < NUM; i++)
//     {
//         pthread_join(tids[i],nullptr);
//     }
//     for(auto& e : tds)
//     {
//         delete e;
//     }

//     pthread_mutex_destroy(&mutex);
//     return 0;
// }